#include<iostream>
#include<vector>
#include<unordered_set>
using namespace std;
/*
给定一个字符串 s ，请你找出其中不含有重复字符的 最长子串的长度。
解题思路：
给定一个子串s=abcabcbb如何能在较低的时间复杂度内找到最长无重复子串
我们可以每次遍历s中的字符规定为子串开头的字符，然后这样每次遍历的子串最后一位也是不断向后遍历的
例如开始时以a作为子串的开头然后遍历剩下的子串(a)bcabcbb
然后遍历到a有(abc)abcbb,接着以b作为子串的开头字符,a(bc)abcbb,因为下一个a之前的元素已经遍历过了，所以不需要再遍历a(bca)bcbb
一次不断这样来进行遍历，可以看出头指针在不断移动，尾指针也不断再向后移动，这样可以使用滑动窗口来做
初始时头指针指向第一个元素，尾指针也指向第一个元素，然后向后移动尾指针，遇到有重复元素就停止移动尾指针，记录结果后
向后移动头指针，接着在重复上述步骤移动尾指针
需要使用unodered_set来去重
*/
int lengthOfLongestSubstring(string s) {
    if(s.size()<1)
        return 0;
    else if(s.size()<2)
        return 1;
    int left=0;
    int right=0;
    int result=0;
    unordered_set<char> set;
    int lenght = 0;
    while(left<s.size()&&right<s.size())
    {
        //如果有重复字符,则将set中原来头指针指向的元素删除头指针向后移动，尾指针恢复
        if(set.find(s[right])!=set.end())
        {
            if(result<lenght)
                result = lenght;
            right--;
            set.erase(s[left]);
            left++;
            lenght--;
        }
        //若无重复元素,则将该元素插入到set中并且向后移动尾指针
        else{
            lenght++;
            set.insert(s[right]);
            right++;
        }
    }
    return result>lenght?result:lenght;
}
int main()
{
    cout<<"enter s:"<<endl;
    string s;
    cin>>s;
    cout<<lengthOfLongestSubstring(s);
    return 0;
}